﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Linq.Expressions;
using Skynet.CommonLibrary.Extension.Serialize;
using System.ServiceModel;
using Skynet.CommonLibrary.ExceptionEx;

namespace ServiceContract
{
    internal class DataCenterOperator
    {
        private static DataCenterOperator _instance = null;
        private DataCenterOperator()
        {
        }

        public static DataCenterOperator Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new DataCenterOperator();
                return _instance;
            }
        }

        private T UsingOpen<T>(Func<DataAccessCenterBase, T> action)
        {
            using (DataAccessCenterBase clientbase = new DataAccessCenterBase())
            {
                try
                {
                    T obj = action(clientbase);
                    clientbase.Close();
                    return obj;
                }
                catch (CommunicationException cx)
                {
                    clientbase.Abort();
                    cx.ProcessException("WCFServiceContract");
                    throw;
                }
                catch (TimeoutException tx)
                {
                    clientbase.Abort();
                    tx.ProcessException("WCFServiceContract");
                    throw;
                }
                catch (Exception ex)
                {
                    clientbase.Close();
                    ex.ProcessException("WCFServiceContract");
                    throw;
                }
            }
        }

        #region IDataAccessCenter 成员

        public byte[] FindEntity<T>(ParamesEntity data, Expression<Func<T, bool>> expression)
        {
            XElement element = new ExpressionSerializer().Serialize(expression);

            return UsingOpen<byte[]>(operate => { return operate.FindEntity(data, element.ToString()); });
        }

        public byte[] FindData(ParamesEntity data)
        {
            return UsingOpen<byte[]>(operate => { return operate.FindData(data); });
        }

        public bool ModifyData(ParamesEntity data)
        {
            return UsingOpen<bool>(operate => { return operate.ModifyData(data); });
        }

        public object GetObject(ParamesEntity data)
        {
            return UsingOpen<object>(operate => { return operate.GetObject(data); });
        }

        #endregion
    }
}
